from datetime import datetime
from flask import g
from flask_restful import Resource
from flask_restful.reqparse import RequestParser
from sqlalchemy.orm import load_only
from app import db
from models.user import Relation, User
from utils.decorators import login_required


class FollowUserResource(Resource):
    method_decorators = {'post': [login_required], 'get': [login_required]}

    def post(self):
        """关注用户视图函数"""

        # 获取参数
        userid = g.userid
        # 创建请求解析器
        parser = RequestParser()
        # 添加参数规则
        parser.add_argument('target', required=True, location='json', type=int)
        # 执行解析
        args = parser.parse_args()
        # 获取参数
        author_id = args.target

        # 查询该用户和作者是否有关系
        relation = Relation.query.options(load_only(Relation.id)).filter(Relation.user_id == userid,
                                                                         Relation.author_id == author_id).first()

        if relation:  # 如果有, 修改记录
            relation.relation = Relation.RELATION.FOLLOW
            relation.update_time = datetime.now()

        else:  # 如果没有, 新增记录
            relation = Relation(user_id=userid, author_id=author_id, relation=Relation.RELATION.FOLLOW)
            db.session.add(relation)

        # 让作者的粉丝数量+1
        User.query.filter(User.id == author_id).update({'fans_count': User.fans_count + 1})
        # 让用户的关注数量+1
        User.query.filter(User.id == userid).update({'following_count': User.following_count + 1})

        db.session.commit()

        # 返回结果
        return {'target': author_id}

    def get(self):
        """获取关注列表
        使用 页码方式 进行分页设计简单,但有两个缺点:
            1.在加载时如果发生数据更新,可能出现重复数据,影响用户体验
            2.这种机制主要利用 LIMIT 偏移量,条数语句进行分页,该语句
            的特点是 查询时间会随偏移量增大而变长(查询过程类似全表扫描),不适合数量大且偏移页多的场景
        """

        """关注列表部分"""
        # 获取参数
        userid = g.userid
        parser = RequestParser()
        parser.add_argument('page', default=1, location='args', type=int)
        parser.add_argument('per_page', default=2, location='args', type=int)
        args = parser.parse_args()
        page = args.page
        per_page = args.per_page

        # 查询数据
        # join连接查询 代替 关联查询 & 当前用户关注列表 & 关注时间倒序 & 使用页码进行分页处理
        # 补充 error_out=False 如果数据为空,返回空数据, 默认True,数据为空,返回404
        pn = User.query.options(load_only(User.id, User.name, User.profile_photo, User.fans_count)). \
            join(Relation, User.id == Relation.author_id). \
            filter(Relation.user_id == userid, Relation.relation == Relation.RELATION.FOLLOW). \
            order_by(Relation.update_time.desc()). \
            paginate(page, per_page, error_out=False)

        """相互关注部分"""

        # 查询当前用户的粉丝列表
        fans_list = Relation.query.options(load_only(Relation.user_id)). \
            filter(Relation.author_id == userid, Relation.relation == Relation.RELATION.FOLLOW).all()

        # 序列化
        author_list = []
        for item in pn.items:
            author_dict = {
                'id': item.id,
                'name': item.name,
                'photo': item.profile_photo,
                'fans_count': item.fans_count,
                'mutual_follow': False      # 是否为互相关注
            }

            # 如果该作者也关注了当前用户, 则为互相关注
            for fans in fans_list:
                # 判断取出的作者 是否在 当前用户的粉丝列表中
                if item.id == fans.user_id:
                    # 相互关注字段设置为True
                    author_dict['mutual_follow'] = True
                    break

            author_list.append(author_dict)

        # 返回数据
        return {'results': author_list, 'per_page': per_page, 'page': pn.page, 'total_count': pn.total}


class UnFollowUserResource(Resource):
    method_decorators = {'delete': [login_required]}

    def delete(self, target):
        """取消关注用户"""

        # 获取参数
        userid = g.userid

        # 更新用户关系(删除关系,逻辑删除,将relation字段更新)
        # Relation.query.filter(Relation.user_id == userid, Relation.author_id == target,Relation.relation == Relation.RELATION.FOLLOW).\
        #     update({'relation': 0, 'update_time': datetime.now()})
        Relation.query.filter(Relation.user_id == userid, Relation.author_id == target,
                              Relation.relation == Relation.RELATION.FOLLOW). \
            update({'relation': Relation.RELATION.DELETE, 'update_time': datetime.now()})

        # 让作者的粉丝数量-1
        User.query.filter(User.id == target).update({'fans_count': User.fans_count - 1})
        # 让用户的关注数量-1
        User.query.filter(User.id == userid).update({'following_count': User.following_count - 1})

        # 提交事务
        db.session.commit()

        # 返回结果
        return {"message": "OK"}
